﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using iWare.Wms.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace iWare.Wms.Application
{
    /// <summary>
    /// 储运部综合管理看板服务
    /// </summary>
    [Route("api/SyntheticalBoard")]
    [ApiDescriptionSettings("仓库看板", Name = "SyntheticalBoard", Order = 112)]

    public class SyntheticalServer : IDynamicApiController, ITransient
    {
        private readonly IRepository<WareLocation, MasterDbContextLocator> _wareLocationRep; //库位表
        private readonly IRepository<WareContainerVsMaterial, MasterDbContextLocator> _wareContainerVsMaterialRep; //库位表
        private readonly IRepository<v_accessrecord, MasterDbContextLocator> _v_accessrecord; //出入库明细试图仓储
        private readonly IRepository<GoodsDelivery, MasterDbContextLocator> _goodsDeliveryRep; //送货单仓储
        private readonly IRepository<CollectDelivery, MasterDbContextLocator> _collectDeliveryRep; //收货单仓储
        private readonly IRepository<CollectDeliveryDetails, MasterDbContextLocator> _collectDeliveryDetailsRep; //收货单明细仓储
        private readonly IRepository<WareOrder, MasterDbContextLocator> _wareOrderRep; //单据表
        private readonly IRepository<WareTask, MasterDbContextLocator> _wareTaskRep; //任务表

        #region 默认
        /// <summary>
        /// 默认
        /// </summary>
        /// <param name="v_accessrecord"></param>
        /// <param name="wareContainerVsMaterialRep"></param>
        /// <param name="wareLocationRep"></param>
        /// <param name="goodsDeliveryRep"></param>
        /// <param name="collectDeliveryRep"></param>
        /// <param name="collectDeliveryDetailsRep"></param>
        /// <param name="wareOrderRep"></param>
        /// <param name="wareTaskRep"></param>
        public SyntheticalServer(
             IRepository<v_accessrecord, MasterDbContextLocator> v_accessrecord,
             IRepository<WareContainerVsMaterial, MasterDbContextLocator> wareContainerVsMaterialRep,
             IRepository<WareLocation, MasterDbContextLocator> wareLocationRep,
             IRepository<GoodsDelivery, MasterDbContextLocator> goodsDeliveryRep,
             IRepository<CollectDelivery, MasterDbContextLocator> collectDeliveryRep,
             IRepository<CollectDeliveryDetails, MasterDbContextLocator> collectDeliveryDetailsRep,
             IRepository<WareOrder, MasterDbContextLocator> wareOrderRep,
             IRepository<WareTask, MasterDbContextLocator> wareTaskRep
         )
        {
            _goodsDeliveryRep = goodsDeliveryRep;
            _wareContainerVsMaterialRep = wareContainerVsMaterialRep;
            _collectDeliveryRep = collectDeliveryRep;
            _collectDeliveryDetailsRep = collectDeliveryDetailsRep;
            _v_accessrecord = v_accessrecord;
            _wareLocationRep = wareLocationRep;
            _wareOrderRep = wareOrderRep;
            _wareTaskRep = wareTaskRep;
        }
        #endregion

        //当天0时0分0秒：
        DateTime start = Convert.ToDateTime(DateTime.Now.ToString("D").ToString());

        //当天23时59分59秒：
        DateTime end = Convert.ToDateTime(DateTime.Now.AddDays(1).ToString("D").ToString()).AddSeconds(-1);

        /// <summary>
        /// 出入库任务
        /// </summary>
        /// <returns></returns>
        [HttpGet("DepotTask")]
        [AllowAnonymous]
        public async Task<TaskOutput> DepotTask()
        {
            var taskList = await _wareTaskRep.Where(z => z.CreatedTime >= start && z.CreatedTime < end).ToListAsync();
            List<TaskSpecifics> taskSpList = new List<TaskSpecifics>();

            foreach (var item in taskList)
            {
                TaskSpecifics taskSpecifics = new TaskSpecifics();
                var location = new WareLocation();

                #region 任务详情赋值
                if (item.TaskType == TaskType.Out) 
                {
                    //任务类型
                    taskSpecifics.TaskType = "出库";

                    //库位类型
                    location = await _wareLocationRep.Where(z => z.Code == item.FromLocationCode).FirstOrDefaultAsync();
                }
                else if (item.TaskType == TaskType.In)
                {
                    //任务类型
                    taskSpecifics.TaskType = "入库";

                    //库位类型
                    location = await _wareLocationRep.Where(z => z.Code == item.ToLocationCode).FirstOrDefaultAsync();
                }
                else if (item.TaskType == TaskType.Move)
                {
                    //任务类型
                    taskSpecifics.TaskType = "移库";

                    //库位类型
                    location = await _wareLocationRep.Where(z => z.Code == item.FromLocationCode).FirstOrDefaultAsync();
                }


                if (location != null)
                {
                    if (location.AreaID == 374444843716677) taskSpecifics.WarehouseType = "立体库";
                    if (location.AreaID == 374444736143429) taskSpecifics.WarehouseType = "平库";
                    if (location.AreaID == 374444777422917) taskSpecifics.WarehouseType = "公共库";
                    if (location.AreaID == 374444685082693) taskSpecifics.WarehouseType = "装配库";
                }
                else
                {
                    if (item.ContainerCode.StartsWith("TJ")) 
                    { 
                        taskSpecifics.WarehouseType = "立体库";
                    }
                    else
                    {
                        taskSpecifics.WarehouseType = "平库";
                    }
                }
                
                #endregion

                //项目编号
                taskSpecifics.ProjectCode = _v_accessrecord.Where(z => z.TaskNo == item.TaskNo).FirstOrDefault().ProjectCode;

                //任务执行数量
                if(item.TaskStatus == TaskStatusEnum.Complete)
                {
                    taskSpecifics.Sum = _v_accessrecord.Where(z => z.TaskNo == item.TaskNo).Sum(e => e.BindQuantity);
                    taskSpecifics.BeNumber = _v_accessrecord.Where(z => z.TaskNo == item.TaskNo).Sum(e => e.BindQuantity);
                    taskSpecifics.NotNumber = 0;
                }
                else
                {
                    taskSpecifics.Sum = _v_accessrecord.Where(z => z.TaskNo == item.TaskNo).Sum(e => e.BindQuantity);
                    taskSpecifics.BeNumber = 0;
                    taskSpecifics.NotNumber = _v_accessrecord.Where(z => z.TaskNo == item.TaskNo).Sum(e => e.BindQuantity);
                }

                taskSpList.Add(taskSpecifics);
            }

            //输出出入库任务信息
            return new TaskOutput()
            {
                TaskSum = taskList.Count,
                TaskBeNumber = taskList.Where(z => z.TaskStatus == TaskStatusEnum.Complete).Count(),
                TaskNotNumber = taskList.Where(z => z.TaskStatus != TaskStatusEnum.Complete).Count(),
                tasks = taskSpList
            };
        }

        /// <summary>
        /// 库位数据信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("LocatorSum")]
        [AllowAnonymous]
        public async Task<LocatorSumOutput> LocatorSum()
        {
            //查询立体库库位信息
            var LlocatorNumber = await _wareLocationRep.Where(z => z.AreaID == 374444843716677).ToListAsync();

            //输出库位数据信息
            return new LocatorSumOutput()
            {
                LStockNumber = LlocatorNumber.Where(z => z.LocationStatus !=LocationStatusEnum.kongxian && z.IsLock == YesOrNot.N).Count(),
                LIdleNumber = LlocatorNumber.Where(z => z.LocationStatus == LocationStatusEnum.kongxian && z.IsLock == YesOrNot.N).Count(),
                PStockNumber = 40,
                PIdleNumber = 100
            };
        }

        /// <summary>
        /// 保质期预警信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("EarlyWarning")]
        [AllowAnonymous]
        public async Task<EarlyWarningOutput> EarlyWarning()
        {
            //创建保质期预警详情
            List<EarlyWarning> earlyWarningList = new List<EarlyWarning>();
            EarlyWarning earlyWarning1 = new EarlyWarning(){GoodsName = "电缆",PresentLocation = "一楼立体库/W1L041206",GoodsNumber = 120,ExpirationTime = DateTime.Now.AddDays(+4).ToString("yy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo)};
            EarlyWarning earlyWarning2 = new EarlyWarning() { GoodsName = "定向轮", PresentLocation = "一楼立体库/W1L031206", GoodsNumber = 200, ExpirationTime = DateTime.Now.AddDays(+3).ToString("yy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo) };
            EarlyWarning earlyWarning3 = new EarlyWarning() { GoodsName = "SMC气管", PresentLocation = "一楼立体库/W1L021206", GoodsNumber = 100, ExpirationTime = DateTime.Now.AddDays(+3).ToString("yy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo) };
            EarlyWarning earlyWarning4 = new EarlyWarning() { GoodsName = "吸盘", PresentLocation = "一楼立体库/W1L021106", GoodsNumber = 80, ExpirationTime = DateTime.Now.AddDays(+4).ToString("yy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo) };
            EarlyWarning earlyWarning5 = new EarlyWarning() { GoodsName = "摩擦片", PresentLocation = "一楼立体库/W1L041206", GoodsNumber = 65, ExpirationTime = DateTime.Now.AddDays(+2).ToString("yy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo) };
            EarlyWarning earlyWarning6 = new EarlyWarning() { GoodsName = "传感器支架", PresentLocation = "一楼平库/W1P05311", GoodsNumber = 125, ExpirationTime = DateTime.Now.AddDays(+5).ToString("yy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo) };
            EarlyWarning earlyWarning7 = new EarlyWarning() { GoodsName = "铝管", PresentLocation = "一楼平库/W1P07411", GoodsNumber = 110, ExpirationTime = DateTime.Now.AddDays(+3).ToString("yy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo) };
            EarlyWarning earlyWarning8 = new EarlyWarning() { GoodsName = "减速机油", PresentLocation = "一楼平库/W1P09511", GoodsNumber = 150, ExpirationTime = DateTime.Now.AddDays(+4).ToString("yy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo) };
            earlyWarningList.Add(earlyWarning1);
            earlyWarningList.Add(earlyWarning2);
            earlyWarningList.Add(earlyWarning3);
            earlyWarningList.Add(earlyWarning4);
            earlyWarningList.Add(earlyWarning5);
            earlyWarningList.Add(earlyWarning6);
            earlyWarningList.Add(earlyWarning7);
            earlyWarningList.Add(earlyWarning8);

            //输出保质期预警信息
            return new EarlyWarningOutput(){GoodsSum = 1050,earlyWarnings = earlyWarningList};
        }

        /// <summary>
        /// 详情信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("Information")]
        [AllowAnonymous]
        public async Task<InformationOutput> Information()
        {
            #region 预约信息
            DocketSpecifics docketSpecifics = new DocketSpecifics();

            //查询送货预约信息
            var goodsDelivery = await _goodsDeliveryRep.DetachedEntities
                .Where(z => z.Status != AuditStatusEnum.yuyuezhong && z.Status != AuditStatusEnum.yuyuechenggong).ToListAsync();

            docketSpecifics.PlanNumber = goodsDelivery.Where(z => z.UpdatedTime > start && z.UpdatedTime < end).Count();
            docketSpecifics.CompleteNumber = goodsDelivery.Where(z => z.UpdatedTime > start && z.UpdatedTime < end && z.Status != AuditStatusEnum.shenhezhong).Count();
            docketSpecifics.SurplusNumber = goodsDelivery.Where(z => z.Status == AuditStatusEnum.shenhezhong).Count();
            docketSpecifics.AgoSurplusNumber = goodsDelivery.Where(z => z.UpdatedTime < start && z.Status == AuditStatusEnum.shenhezhong).Count();

            var goodsDeliveryNot = goodsDelivery.Where(z => z.Status == AuditStatusEnum.shenhezhong).OrderByDescending(p => p.CreatedTime).ToList();
            List <Docket> listDocket = new List<Docket>();

            //循环赋值
            foreach (var item in goodsDeliveryNot)
            {
                Docket docket = new Docket()
                {
                    ProjectCode = item.DeliveryNo,
                    Number = item.DeliveryQuantityTotal,
                    PassNumber = item.DeliveryQuantityTotal,
                };
                listDocket.Add(docket);
            }
            docketSpecifics.dockets = listDocket;
            #endregion

            #region 收货信息
            DocketSpecifics docketSpecifics1 = new DocketSpecifics();

            //查询今日收货信息
            var Inspect = await _collectDeliveryRep.Where(z => z.IsDeleted == false && z.CreatedTime > start && z.CreatedTime < end).ToListAsync();

            //查询预计今日收货信息
            var NotDeliveryNum = await _goodsDeliveryRep.Where(z => z.Status >= AuditStatusEnum.shenhetongguo
            && z.GoodsDeliveryAppointments.EstimatedDate >= start && z.GoodsDeliveryAppointments.EstimatedDate < end).ToListAsync();

            //查询今日之前未完成收货信息
            var NotDeliveryNum1 = await _goodsDeliveryRep.Where(z => z.Status == AuditStatusEnum.songhuozhong
            && z.GoodsDeliveryAppointments.EstimatedDate < start).ToListAsync();

            

            docketSpecifics1.PlanNumber = NotDeliveryNum.Count();
            docketSpecifics1.CompleteNumber = Inspect.Count();
            docketSpecifics1.SurplusNumber = NotDeliveryNum.Count() - Inspect.Count() < 0 ? 0 : NotDeliveryNum.Count() - Inspect.Count();//+ NotDeliveryNum1.Count;
            docketSpecifics1.AgoSurplusNumber = 0;//NotDeliveryNum1.Count;

            var goodsDeliveryNot1 = _goodsDeliveryRep.Where(z => z.Status == AuditStatusEnum.songhuozhong
            && z.GoodsDeliveryAppointments.EstimatedDate < end).OrderByDescending(p => p.CreatedTime).ToList();
            List<Docket> listDocket1 = new List<Docket>();

            //循环赋值
            foreach (var item in NotDeliveryNum)
            {
                Docket docket = new Docket()
                {
                    ProjectCode = item.DeliveryNo,
                    Number = item.DeliveryQuantityTotal,
                    PassNumber = item.DeliveryQuantityTotal,
                };
                listDocket1.Add(docket);
            }

            docketSpecifics1.dockets = listDocket1;
            #endregion

            #region 入库信息
            DocketSpecifics docketSpecifics2 = new DocketSpecifics();

            //查询任务信息
            var taskList = await _wareTaskRep.Where(z => z.TaskType == TaskType.In).ToListAsync();

            docketSpecifics2.PlanNumber = taskList.Where(z => z.CreatedTime > start && z.CreatedTime < end).Count();
            docketSpecifics2.CompleteNumber = taskList.Where(z => z.CreatedTime > start && z.CreatedTime < end && z.TaskStatus == TaskStatusEnum.Complete).Count();
            docketSpecifics2.SurplusNumber = taskList.Where(z => z.TaskStatus != TaskStatusEnum.Complete).Count();
            docketSpecifics2.AgoSurplusNumber = taskList.Where(z => z.CreatedTime < start && z.TaskStatus != TaskStatusEnum.Complete).Count();

            List<Docket> listDocket2 = new List<Docket>();

            //循环赋值
            foreach (var item in taskList.Where(z => z.TaskStatus != TaskStatusEnum.Complete))
            {
                //查询组盘信息
                var query = await _wareContainerVsMaterialRep.Where(z => z.OrderNo == item.OrderNo).FirstOrDefaultAsync();
                Docket docket = new Docket()
                {
                    ProjectCode = item.OrderNo,
                    Number = query.BindQuantity,
                    PassNumber = query.BindQuantity,
                };
                listDocket2.Add(docket);
            }

            docketSpecifics2.dockets = listDocket2;
            #endregion

            #region 调拨信息
            DocketSpecifics docketSpecifics3 = new DocketSpecifics();

            //查询单据信息
            var orderList = await _wareOrderRep.DetachedEntities.ToListAsync();

            docketSpecifics3.PlanNumber = orderList.Where(z => z.CreatedTime > start && z.CreatedTime < end).Count();
            docketSpecifics3.CompleteNumber = orderList.Where(z => z.CreatedTime > start && z.CreatedTime < end && z.OrderStatus == IssueStausEnum.WANCHENG).Count();
            docketSpecifics3.SurplusNumber = Convert.ToInt32(docketSpecifics3.PlanNumber) - Convert.ToInt32(docketSpecifics3.CompleteNumber);//orderList.Where(z => z.OrderStatus != IssueStausEnum.WANCHENG).Count();
            docketSpecifics3.AgoSurplusNumber = 0;//orderList.Where(z => z.CreatedTime < start && z.OrderStatus != IssueStausEnum.WANCHENG).Count();

            List<Docket> listDocket3 = new List<Docket>();

            //循环赋值
            foreach (var item in orderList.Where(z => z.OrderStatus != IssueStausEnum.WANCHENG && z.CreatedTime > start && z.CreatedTime < end))
            {
                Docket docket = new Docket()
                {
                    ProjectCode = item.OrderNo,
                    Number = item.OrderQuantityTotal,
                    PassNumber = item.OrderQuantityTotal,
                };
                listDocket3.Add(docket);
            }

            docketSpecifics3.dockets = listDocket3;
            #endregion

            //创建单据信息
            List<Docket> docketList4 = new List<Docket>();
            for (int i = 0; i < 9; i++)
            {
                if (i == 0 || i == 2 || i == 8 || i == 5)
                {
                    Docket docket4 = new Docket() { ProjectCode = "405" + i + "1049" + i + 1 + "031045", Number = i * 4 + 10, PassNumber = i * 4 + 10, };
                    docketList4.Add(docket4);
                }
                else
                {
                    Docket docket4 = new Docket() { ProjectCode = "40" + i + 1+ "1973" + i+1  + "3702214", Number = i * 10, PassNumber = i * 10, };
                    docketList4.Add(docket4);
                }

            }

            DocketSpecifics docketSpecifics4 = new DocketSpecifics() { PlanNumber = 100, CompleteNumber = 60, SurplusNumber = 40, AgoSurplusNumber = 0, dockets = docketList4, };


            //输出出入库任务信息
            return new InformationOutput()
            {
                SubscribeSpecifics = docketSpecifics,
                CollectSpecifics = docketSpecifics1,
                EntrySpecifics = docketSpecifics2,
                AllocateSpecifics = docketSpecifics3,
                DeliverySpecifics = docketSpecifics4
            };
        }
    }
}
